from django.shortcuts import render
from django.core.exceptions import ObjectDoesNotExist
from dappx.forms import UserForm,UserProfileInfoForm,UploadFileForm, UpdateCommentsForm
from django.contrib.auth import authenticate, login, logout
from django.http import HttpResponseRedirect, HttpResponse, JsonResponse
from django.urls import reverse
from django.contrib.auth.decorators import login_required
from dappx.models import LogFile, summary, highmemdetec, propcompare, sharetable, knownissue, hierachy, pollingdata
from django.contrib.auth.models import User
from ids_encoder import encode_id, decode_id
import os.path as op
import os
import time
import socket
import csv
import sys
import threading
import gzip
import tarfile
import json

class SerConf:
    STRING_FETCH_ERROR = "Error: cannot fetch data!"
    STRING_SHARE_ERROR = "Error: share log file failed!"
    STRING_MISSING_LOG = "Error: log dose not exist!"
    STRING_PERMISSION_ISSUE = "Error: permission required!"

@login_required
def index(request):
    if request.method == 'GET':
        if request.is_ajax():
            template = 'dappx/log-table.html'
            username = User.objects.get(username=request.user)
            logs = LogFile.objects.filter(postedby = username).order_by('postime')
            context = {
                        "logs": logs
                     }
            return render(request, template, context)
        else:
            template = 'dappx/index.html'
            return render(request, template)

    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        # import pdb; pdb.set_trace();
        if form.is_valid():
            saved_path = handle_uploaded_file(request.user, request.FILES['file'])
        else:
            return HttpResponse(status=500)

        username = User.objects.get(username=request.user)
        logObj = LogFile.objects.create(
                            fullfilename = saved_path,
                            filename = request.FILES['file'].name,
                            postedby= username)
        
        try:
            logObj.save()
            status= dict({'log_id': logObj.id, 'status': 0})
        except:
            status= dict({'status': -1})

        # Sub thread non-block.
        # subThread = threading.Thread(target=extract_files, args=(saved_path, logObj.id, ))
        # subThread.start()
        update_log_status(logObj.id, "File Uploaded")
        backend_connect(logObj.id, operation="FILEUPLOADED")
        return JsonResponse(status)


def extract_files(file_path, log_id):
    un_gz(file_path, log_id)
    backend_connect(log_id, operation="FILEUPLOADED")

def update_log_status(log_id, status):
    logObj = LogFile.objects.get(id=log_id)
    logObj.status = status
    logObj.save()

def un_gz(file_name, log_id):

    update_log_status(log_id, "Start Extracting.")

    if not op.isfile(file_name) or not file_name.endswith(".tar.gz"):
        update_log_status(log_id, "Invalid GZ File.")
        return

    fn = op.basename(file_name)
    fd = op.dirname(file_name)
    t_name = op.join(fd, fn.replace(".tar.gz",""))

    try:
        f_handle = tarfile.open(file_name, mode='r:gz')
        total_files = f_handle.getnames()
        cnt = len(total_files)
        for idx, f in enumerate(total_files):
            f = f.replace(":","_")
            try:
                f_handle.extract(f, t_name)
            except:
                continue
            if idx%200==0:
                status="Extracting %.1f%%"%(100*float(idx/(cnt+0.01)))
                update_log_status(log_id, status)
        f_handle.close()
        status="Extraction Done"
        update_log_status(log_id, status)
    except:
        status="File Extraction Failed"
        update_log_status(log_id, status)
        return

@login_required
def fetch_table_data(request):
    if request.method == 'GET':
        username = User.objects.get(username=request.user)
        # import pdb; pdb.set_trace()
        context = { "user": username.username,
                    "error": 0,
                  }
        logs = list(LogFile.objects.filter(postedby=username).order_by('-postime').exclude(status="del").values())
        # obfuscate url
        for log in logs:
            log['id'] = encode_id(log['id'])

        context.update({
                    "data": logs ,
                  })
        return JsonResponse(context)


@login_required
def genid(request, log_id):
    try:
        logObj=LogFile.objects.get(id=log_id, postedby=request.user)
        return JsonResponse({'encode_id': encode_id(log_id),
            'error': 0})
    except ObjectDoesNotExist:
        return JsonResponse({'error': SerConf.STRING_PERMISSION_ISSUE})


@login_required
def delete_logs(request, log_ids):

    log_ids = [decode_id(log_id) for log_id in log_ids.split(',')]
    num_del = 0
    for log_id in log_ids:
        try:
            logObj = LogFile.objects.get(id=log_id, postedby=request.user)
            log_path = logObj.fullfilename
        except ObjectDoesNotExist:
            logObj = None
        # <-> Error code should be defined <-> #
        if logObj != None:
            try:
                print("Remove: "+logObj.fullfilename)
                # os.remove(log_path)
                logObj.status = "del"
                logObj.save()
                num_del += 1
            except:
                # <-> error handling <->#
                pass
        else:
            # <-> error handling <-> #
            pass
                

    print(num_del, log_ids)
    if num_del == len(log_ids):
        return JsonResponse({'status': 0})
    else:
        return JsonResponse({'status': 1})

@login_required
def share_log(request, log_id):
    if request.method == 'GET':
        context = {
                "log_id": log_id,
                "error": 0
                }
        logObj = LogFile.objects.get(id=log_id)
        if logObj.shared or request.user.username == logObj.postedby.username:
            try:
                logObj = LogFile.objects.get(id=log_id)
                # context.update({'summary': summary_obj})
                logObj.shared = True
                logObj.save()
            except ObjectDoesNotExist:
                context["error"] = SerConf.STRING_SHARE_ERROR
        else:
            context["error"] = SerConf.STRING_MISSING_LOG
        return JsonResponse(context)

@login_required
def unshare_log(request, log_id):
    if request.method == 'GET':
        context = {
                "log_id": log_id,
                "error": 0
                }
        logObj = LogFile.objects.get(id=log_id)
        if logObj.shared or request.user.username == logObj.postedby.username:
            try:
                logObj = LogFile.objects.get(id=log_id)
                # context.update({'summary': summary_obj})
                logObj.shared = False
                logObj.save()
            except ObjectDoesNotExist:
                context["error"] = SerConf.STRING_SHARE_ERROR
        else:
            context["error"] = SerConf.STRING_MISSING_LOG
        return JsonResponse(context)

@login_required
def analyze_log(request, log_id):
    try:
        logObj = LogFile.objects.get(id=log_id, postedby=request.user)
        log_path = logObj.fullfilename
    except ObjectDoesNotExist:
        logObj = None

    if logObj != None:
        context = {'log_id': log_id,
                   'filename': logObj.filename,
                   'techsupptype': logObj.techsupptype,
                   'comments':logObj.comments}
        return render(request,'dappx/analyze.html', context)
    else:
        #<-> Error handling is needed. <->#
        return render(request,'dappx/404.html')
    

@login_required
def access_share(request, log_id):
    if request.method == 'GET':
        context = {'log_id': log_id,
                   'error': 0,
                  }
        try:
            logObj = LogFile.objects.get(id=log_id)
            if logObj.shared:
                context.update({'share': True,
                                'filename': logObj.filename,
                                'sharefrom': logObj.postedby.username,
                                'techsupptype': logObj.techsupptype,
                                })
            else:
                context.update({'error':  SerConf.STRING_PERMISSION_ISSUE})
                return render(request,'dappx/permission_deny.html')
        except ObjectDoesNotExist:
            context.update({'error':  SerConf.STRING_MISSING_LOG})
            return render(request,'dappx/permission_deny.html')

        # import pdb; pdb.set_trace()

        try:
            shareobj = sharetable.objects.get(shareid=log_id, sharedto=request.user)
            shareobj.accesstimes = shareobj.accesstimes + 1
            shareobj.save()
        except ObjectDoesNotExist:
            shareobj = sharetable.objects.create(
                    shareid=logObj,
                    sharedto=request.user,
                    openby=str(request.user),
                    logname=logObj.filename,
                    accesstimes=1,
                    )
            shareobj.save()

        if context['error'] == 0 :
            return render(request,'dappx/analyze.html', context)
        else:
            #<-> Error handling is needed. <->#
            return render(request,'dappx/permission_deny.html')

@login_required
def share_track(request, log_id):
    if request.method == 'GET':
        context = {'log_id': log_id,
                   'error': 0,
                  }
        try:
            logObj = LogFile.objects.get(id=log_id, postedby=request.user)
            querry_results=sharetable.objects.filter(shareid=log_id).values()
            entries = [x for x in querry_results]
            context.update({
                "num_entry": len(entries),
                "entries": entries})
        except ObjectDoesNotExist:
                context.update({'error':  SerConf.STRING_PERMISSION_ISSUE})

        return render(request,'dappx/share-tracking.html', context)



@login_required
def analyze_operation(request, log_id):

    try:
        logObj = LogFile.objects.get(id=log_id, postedby=request.user)
    except ObjectDoesNotExist:
        logObj = None

    if logObj != None:
        status = backend_connect(log_id, operation="FILEUPLOADED")
        return JsonResponse({'status': status})
    else:
        return JsonResponse({'status': -1})


def handle_uploaded_file(user, f):
    if sys.platform == "win32":
        file_center = "E:\\haihuam\\Projects\\dprojx\\uploadfiles"
    else:
        file_center = "/home/haihuam/Projects/dprojx/uploadfiles"

    user_file_dir = op.join(file_center, str(user))
    if not op.exists(user_file_dir):
        try: 
            os.makedirs(user_file_dir)
        except:
            # Directories created failed.
            return 

    file_name = "_".join([str(int(time.time())), f.name])
    file_save_path = op.join(user_file_dir, file_name)

    with open(file_save_path, 'wb+') as destination:
        for chunk in f.chunks():
            destination.write(chunk)

    return file_save_path

@login_required
def special(request):
    return HttpResponse("You are logged in !")

@login_required
def user_logout(request):
    logout(request)
    return HttpResponseRedirect(reverse('index'))

def register(request):
    if request.method == 'POST':
        user_form = UserForm(data=request.POST)
        
        if user_form.is_valid() :
            user = user_form.save()
            user.set_password(user.password)
            user.save()
            return HttpResponseRedirect(reverse('index'))
        else:
            print(user_form.errors)
    else:
        user_form = UserForm()
    return render(request,'dappx/register.html',
                          {'errors': user_form.errors})

def user_login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        user = authenticate(username=username, password=password)
        if user:
            if user.is_active:
                login(request,user)
                return HttpResponseRedirect(reverse('index'))
            else:
                return HttpResponse("Your account was inactive.")
        else:
            print("Someone tried to login and failed.")
            print("They used username: {} and password: {}".format(username,password))
            return HttpResponse("Invalid login details given")
    else:
        return render(request, 'dappx/login.html', {})

def backend_connect(logid, operation="FILEUPLOADED"):
    logid = str(logid)
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect(('localhost', 8882))
        data = s.recv(1024)
        s.sendall(";".join([operation, logid]).encode('utf-8'))
        res = str(s.recv(1024).strip(), 'ascii')
        s.close()
        if res=="200_OK":
            return 0
        else: 
            return 1
    except: 
        return 1

def trigger_polling(node_id, operation="POLLINGDATA"):
    node_id = str(node_id)
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect(('localhost', 8882))
        data = str(s.recv(1024).strip(), 'ascii')
        s.sendall(";".join([operation, node_id]).encode('utf-8'))
        res = str(s.recv(1024).strip(), 'ascii')
        # with open("/home/haihuam/temp.log", "a+") as f:
        #     f.write("Res:%s, data:%s\n"%(res, data))
        s.close()
        if res=="200_OK":
            return 0
        else: 
            return 1
    except: 
        return 1


@login_required
def fetch_summary(request, log_id):
    if request.method == 'GET':
        context = {
                "log_id": log_id,
                "error": 0
                }
        logObj = LogFile.objects.get(id=log_id)
        if logObj.shared or request.user.username == logObj.postedby.username:
            try:
                summary_obj = summary.objects.get(techsuppid=log_id)
                context.update({'summary': summary_obj})
            except ObjectDoesNotExist:
                context["error"] = SerConf.STRING_FETCH_ERROR
            return render(request, 'dappx/summary.html', context)
        else:
            # error handle.
            print("Error: %s dose not own the log."%request.user)
            return render(request, 'dappx/fetch_error.html')

@login_required
def fetch_description(request, log_id, scanid):
    if request.method == 'GET':
        context = {
                "log_id": log_id,
                "error": 0,
                "scanid": scanid,
                }
        logObj = LogFile.objects.get(id=log_id)
        if logObj.shared or request.user.username == logObj.postedby.username:
            try:
                querry_results = list(knownissue.objects.filter(id=scanid).values('detail_info'))[0]
                context.update(querry_results)
            except ObjectDoesNotExist:
                context["error"] = SerConf.STRING_FETCH_ERROR
            return render(request, 'dappx/knownissue_description.html', context)
        else:
            # error handle.
            print("Error: %s dose not own the log."%request.user)
            return render(request, 'dappx/fetch_error.html')


@login_required
def fetch_knownissue(request, log_id):
    if request.method == 'GET':
        context = {
                "log_id": log_id,
                "error": 0
                }
        logObj = LogFile.objects.get(id=log_id)
        if logObj.shared or request.user.username == logObj.postedby.username:
            return render(request, 'dappx/knownissue.html', context)
        else:
            # error handle.
            context["error"] = SerConf.STRING_FETCH_ERROR
            return render(request, 'dappx/knownissue.html', context)

@login_required
def fetch_knownissue_json(request, log_id):
    context = {
            "log_id": log_id,
            "error": 0
            }
    if request.method == 'GET':
        logObj = LogFile.objects.get(id=log_id)
        if logObj.shared or request.user.username == logObj.postedby.username:
            columns = ('id', 'name', 'healthy_level', 'short_description', 'scantype')
            querry_results = list(knownissue.objects.filter(techsuppid=log_id).values(*columns))
            context.update({
                "data": querry_results,
                })
        else:
            context["error"] = SerConf.STRING_FETCH_ERROR
    else:
        # error handle.
        context["error"] = SerConf.STRING_FETCH_ERROR
    return JsonResponse(context)


@login_required
def comment_update(request, log_id):
    if not LogFile.objects.filter(id=log_id, postedby=request.user).exists():
        print("Error: %s dose not own the log."%request.user)
        result = {'status':1}
        return JsonResponse(result)

    if request.method == 'GET':
        try:
            logObj = LogFile.objects.get(id=log_id)
            result = {'status':0, 'comments': logObj.comments}
            return JsonResponse(result)
        except ObjectDoesNotExist:
            result = {'status':1}
            return JsonResponse(result)

    elif request.method == 'POST':
        form = UpdateCommentsForm(request.POST)
        # import pdb; pdb.set_trace()
        if form.is_valid():
            try:
                comments = request.POST['comments']
                logObj = LogFile.objects.get(id=log_id)
                logObj.comments = comments
                logObj.save()
                result = {'status':0}
                return JsonResponse(result)
            except ObjectDoesNotExist:
                result = {'status':1}
                return JsonResponse(result)
        else:
            result = {'status':1, 'error': "Form is invalid."}
            return JsonResponse(result)
    else:
        result = {'status':1, 'error': "Invalid request type."}
        return JsonResponse(result)

@login_required
def fetch_memory(request, log_id):
    if request.method == 'GET':
        context = {
                "log_id": log_id,
                "error": 0
                }
        logObj = LogFile.objects.get(id=log_id)
        if logObj.shared or request.user.username == logObj.postedby.username:
            return render(request, 'dappx/memory.html', context)
        else:
            context["error"] = SerConf.STRING_FETCH_ERROR
            return render(request, 'dappx/memory.html', context)

@login_required
def fetch_memory_json(request, log_id):
    context = {
            "log_id": log_id,
            "error": 0
            }
    if request.method == 'GET':
        logObj = LogFile.objects.get(id=log_id)
        if logObj.shared or request.user.username == logObj.postedby.username:
            columns = ('processname', 'memoryfile', 'heapsize', 'maximumutil','restartcounter')
            querry_results = list(highmemdetec.objects.filter(techsuppid=log_id).values(*columns))
            context.update({
                "data": querry_results,
                })
        else:
            context["error"] = SerConf.STRING_FETCH_ERROR
    else:
        # error handle.
        context["error"] = SerConf.STRING_FETCH_ERROR
    return JsonResponse(context)




@login_required
def fetch_memory_table_data(request, processname, column,  log_id):
    if request.method == 'GET':
        context = {
                "process": processname,
                "column": column,
                "error": 0
                }

        logObj = LogFile.objects.get(id=log_id)
        if logObj.shared or request.user.username == logObj.postedby.username:
            try:
                querry_results = highmemdetec.objects.filter(techsuppid=log_id, processname=processname).values_list(column)
                # ---> Note: hard code here for w/a

                details = "\n".join([str(entry[0]) for entry in querry_results])

                if len(details) < 1:
                    context["error"] = SerConf.STRING_FETCH_ERROR
                else:
                    context.update({
                            "details": details
                            })
                     
            except ObjectDoesNotExist:
                context["error"] = SerConf.STRING_FETCH_ERROR

            return render(request, 'dappx/memory_detail.html', context)

        else:
            context["error"] = SerConf.STRING_FETCH_ERROR
            return render(request, 'dappx/memory_detail.html', context)

@login_required
def fetch_memory_detail(request, processname, column,  log_id):
    if request.method == 'GET':
        context = {
                "log_id": log_id,
                "process": processname,
                "column": column,
                "error": 0
                }
        logObj = LogFile.objects.get(id=log_id)
        if logObj.shared or request.user.username == logObj.postedby.username:
            try:
                querry_results = highmemdetec.objects.filter(techsuppid=log_id, processname=processname).values_list(column)

                # ---> Note: hard code here for w/a

                details = "\n".join([str(entry[0]) for entry in querry_results])

                if len(details) < 0:
                    context['error'] = SerConf.STRING_FETCH_ERROR
                else:
                    context.update({
                            "details": details
                            })
                     
            except ObjectDoesNotExist:
                context['error'] = SerConf.STRING_FETCH_ERROR

            return render(request, 'dappx/memory_detail.html', context)
        else:
            
            print("Error: %s dose not own the log."%request.user)
            context["error"] = SerConf.STRING_FETCH_ERROR
            return render(request, 'dappx/memory_detail.html', context)


@login_required
def fetch_process_table(request, processname, log_id):
    if request.method == 'GET':
        context = { 
                "log_id": log_id,
                "process": processname,
                "error": 0,
                }
        logObj = LogFile.objects.get(id=log_id)
        if logObj.shared or request.user.username == logObj.postedby.username:
            obj = highmemdetec.objects.get(techsuppid=log_id, processname=processname)
            data_file_path = obj.summarylog

            if not op.exists(data_file_path):
                context["error"] = "%s does not exist."%data_file_path

            return render(request, 'dappx/process_table.html', context )
        else:
            context["error"] = "No data for this log."
            return render(request, 'dappx/process_table.html', context)

@login_required
def fetch_propdiff(request, log_id):
    if request.method == 'GET':
        context = { 
                "log_id": log_id,
                "error": 0,
                }
        logObj = LogFile.objects.get(id=log_id)
        if logObj.shared or request.user.username == logObj.postedby.username:
            columns = ('propname', 'diff', 'propfullname', 'mismatched','extra', 'missing', 'difffilename')
            obj = propcompare.objects.filter(techsuppid=log_id).values_list(*columns)

            diff_prop = [x[0] for x in obj]
            diff_detail = [x for x in obj]
            context.update({
                "diff_prop": diff_prop,
                "diff_detail": diff_detail,
                "columns": columns})
            # return JsonResponse(context)
            return render(request, 'dappx/propcompare.html', context)

        else:
            context["error"] = "No data for this log."
            return render(request, 'dappx/propcompare.html', context)

def fetch_propfile(request, log_id, propname):
    if request.method == 'GET':
        context = { 
                "log_id": log_id,
                "propname": propname,
                "error": 0,
                }
        logObj = LogFile.objects.get(id=log_id)
        if logObj.shared or request.user.username == logObj.postedby.username:
            columns = ('propfullname')
            obj = propcompare.objects.get(techsuppid=log_id, propname=propname)
            if obj:
                propfullname = obj.propfullname
                print("Open file %s"%propfullname)
                if os.path.exists(propfullname):
                    file_content = str()
                    with open(propfullname, 'r', encoding="utf8") as f:
                        file_content = f.read()
                    context.update({"file_content": file_content})
                else:
                    context["error"] = "No data for this log."
            else:
                context["error"] = "No data for this log."
            
            return render(request, 'dappx/propfile.html', context)

        else:
            context["error"] = "No data for this log."
            return render(request, 'dappx/propfile.html', context)

@login_required
def fetch_process_chart_data(request, processname, log_id):
    if request.method == 'GET':
        context = { 
                "log_id": log_id,
                "process": processname,
                "error": 0,
                }

        x_axis = list()
        mem_util = list()
        restart = list()

        obj = highmemdetec.objects.get(techsuppid=log_id, processname=processname)
        data_file_path = obj.summarylog

        with open(data_file_path, 'r', encoding="utf8") as f:
            readCSV = csv.reader(f, delimiter=',')
            for row in readCSV:
                x_axis.append(row[0])
                mem_util.append(row[1])
                if int(row[2]) == 1:
                    restart.append({
                        "name":"coordinate",
                        "coord": [row[0].replace(" ", "\n"), row[1]],
                        "value": "restart"
                        })

        context.update({
                "x_axis": x_axis,
                "mem_util" : mem_util,
                "restart" : restart,
                })

        return JsonResponse(context)


@login_required
def fetch_polling(request, log_id):
    if request.method == 'GET':
        context = { 
                "log_id": log_id,
                "error": 0,
                }
        logObj = LogFile.objects.get(id=log_id)
        if logObj.shared or request.user.username == logObj.postedby.username:
            # context["error"] = "No data for this log."
            # return render(request, 'dappx/polling.html', context)
            # pass
            return render(request, 'dappx/polling.html', context)
        else:
            context["error"] = "No data for this log."
            return render(request, 'dappx/polling.html', context)

@login_required
def fetch_polling_json(request, log_id):
    if request.method == 'GET':
        context = { 
                "log_id": log_id,
                "error": 0,
                }
        logObj = LogFile.objects.get(id=log_id)
        if logObj.shared or request.user.username == logObj.postedby.username:
            all_entries = list(hierachy.objects.filter(techsuppid=log_id).values())
            l0, l1, l2 = [],[],[]
            for entry in all_entries:
                lvl = entry['level']
                if lvl == "0":
                    l0.append(entry)
                elif lvl == "1":
                    l1.append(entry)
                else:
                    l2.append(entry)

            data = dict()

            for e_0 in l0:
                e_0_id = e_0['id']
                e_0_name = e_0['mename']
                e_0_meversion = e_0['meversion']
                e_0_children = list()
                e_0_weekday = e_0['weekday'].upper().replace(" ","").replace("=", "-")
                e_0_cols = e_0['colsname']
                for e_1 in l1:
                    if e_1["parentname"] == str(e_0_id):
                        e_1_children = list()
                        e_1_name = e_1['mename']
                        e_1_meversion = e_1['meversion']
                        e_1_id = e_1['id']
                        e_1_cols = e_1['colsname']
                        for e_2 in l2:
                            if e_2['parentname'] == str(e_1_id):
                                e_2_name = e_2['mename']
                                e_2_id = e_2['id']
                                e_2_cols = e_2['colsname']
                                e_1_children.append({"name": "if"+e_2_name,
                                                     "node_id": e_2_id,
                                                     "symbol": "pin", 
                                                     "symbolSize": "10", 
                                                     "node_name": "&".join([e_0_weekday, e_1_name, e_2_name]),
                                                     "cols": e_2_cols})
                        e_0_children.append({"name":"\n".join([e_1_name, e_1_meversion]), 
                                             "cols":e_1_cols,
                                             # "value": "1",
                                             "symbol": "image:///static/img/server.svg", 
                                             "node_id": e_1_id,
                                             "node_name": "&".join([e_0_weekday, e_1_name]),
                                             "children": e_1_children
                            })
                data.update({e_0_weekday: {"name": "\n".join([e_0_weekday, e_0_name, e_0_meversion]),
                                           "cols": e_0_cols,
                                           "node_id": e_0_id,
                                           "node_name": e_0_weekday,
                                           "children": e_0_children}})
            return JsonResponse(data)

        else:
            context["error"] = "No data for this log."
            return render(request, 'dappx/polling.html', context)

@login_required
def check_node_data_ready(request, log_id, node_id):
    if request.method == 'GET':
        context = { 
                "log_id": log_id,
                "node_id": node_id,
                "error": 0,
                }

        node_obj = hierachy.objects.get(techsuppid=log_id, id=node_id)
        context.update({
                "dataloaded": node_obj.dataloaded,
                "pinged": node_obj.status,
                "colsname": node_obj.colsname,
            })        
        if node_obj.status == "pinged": 
            print("Already pinged")
        else:
            res = trigger_polling(node_id)
            if res == 0:
                print("Ping successfully, node_id: %s"%node_id)
                node_obj.status = "pinged"
                node_obj.save()
            else:
                print("Ping failed.")
        return JsonResponse(context)

@login_required
def fetch_polling_page_detail(request, log_id, node_id, node_name):
    if request.method == 'GET':
        context = { 
                "log_id": log_id,
                "node_id": node_id,
                "node_name": node_name.replace("&", "/"),
                "error": 0,
                }
        return render(request, 'dappx/polling_detail.html', context)

@login_required
def fetch_polling_detail_data(request, log_id, node_id):
    if request.method == 'GET':
        context = { 
                "log_id": log_id,
                "node_id": node_id,
                "error": 0,
                }
        entries = list(pollingdata.objects.filter(techsuppid=log_id, hierachynodeid=node_id).values())
        context.update(
                {"data": entries}
        )
        return JsonResponse(context)

